package com.atguigu.exam.service.impl;


import com.atguigu.exam.entity.Category;
import com.atguigu.exam.entity.Question;
import com.atguigu.exam.mapper.CategoryMapper;
import com.atguigu.exam.mapper.QuestionMapper;
import com.atguigu.exam.service.CategoryService;
import com.atguigu.exam.service.QuestionService;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;


@Slf4j
@Service
public class CategoryServiceImpl extends ServiceImpl<CategoryMapper,Category> implements  CategoryService {
    @Autowired
    private CategoryMapper categoryMapper;
    @Autowired
    private QuestionService questionService;
    @Autowired
    private QuestionMapper questionMapper;

    /**
     * 获取所有分类列表同时查询题目数量
     * @return
     */

    @Override
    public List<Category> getAllCategories() {
        //思想：先对分类表进行查询并且进行排序,其次查询题目的分类和数量，最后取出数量进行拼接到题目分类表中
        //查询所有分类并排序
        LambdaQueryWrapper<Category> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.orderByAsc(Category::getSort);//sort正序排序
        List<Category> categoryList = list(queryWrapper);
        //查询每个分类的题目数量
        List<Map<String, Long>> categoryQuestionCount = categoryMapper.getCategoryQuestionCount();

        Map<Long, Long> countMap = categoryQuestionCount.stream()
                .collect(Collectors
                        .toMap(m -> m.get("category_id"), m -> m.get("count")));
        //通过ID匹配，把数量填到分类对象中
        for (Category category : categoryList) {
            Long id = category.getId();
            category.setCount(countMap.getOrDefault(id,0L));//如果查询不到给一个默认值0
        }

//        //取出题目的数量count
//        for (Category category : categoryList) {
//            Long id = category.getId();
//            for (Map<String, Long> longMap : categoryQuestionCount) {
//                Long categoryId = longMap.get("categoryId");
//                if(id==categoryId){
//                    category.setCount(longMap.get("count"));
//                }
//            }
//        }

        //将题目的数量放入到题目分类列表中
        return categoryList;
    }

    @Override
    public List<Category> getCategoryTree() {
        //获取题目的分类并按照sort进行排序
        LambdaQueryWrapper<Category> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.orderByAsc(Category::getSort);
        List<Category> categoryList = list(queryWrapper);
        //获取题目分类的题目数量
        List<Map<String, Long>> categoryQuestionCount = categoryMapper.getCategoryQuestionCount();

        Map<Long, Long> countMap = categoryQuestionCount.stream().collect(Collectors.
                toMap(m -> m.get("category_id"), m -> m.get("count")));
        //将获取到的题目数量整合到题目分类里面
        for (Category category : categoryList) {
            Long categoryId = category.getId();
            category.setCount(countMap.getOrDefault(categoryId,0L));
        }
        //分类信息进行分组(stream进行分组)
        Map<Long, List<Category>> longListMap = categoryList.stream()
                .collect(Collectors.groupingBy(Category::getParentId));
        //获取到一级分类
        List<Category> parentCategoryList = categoryList.stream()
                .filter(c -> c.getParentId() == 0L)
                .collect(Collectors.toList());
        //循环一级分类将二级分类整合到一级分类中,并且计算count
        for (Category parentCategory : parentCategoryList) {
            Long categoryId = parentCategory.getId();
            List<Category> sonCategoryList = longListMap.getOrDefault(categoryId, new ArrayList<>());
            parentCategory.setChildren(sonCategoryList);

            Long sonCount = sonCategoryList.stream().collect(Collectors.summingLong(Category::getCount));
            parentCategory.setCount(parentCategory.getCount() + sonCount);
        }
        return parentCategoryList;
    }

    /**
     * 添加分类
     */
    @Override
    public void addCategory(Category category) {
        //判断同一个父类分类下不允许重名
        LambdaQueryWrapper<Category> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(Category::getParentId,category.getParentId());
        queryWrapper.eq(Category::getId,category.getId());
        long count = count(queryWrapper);
        //如果有进行报错
        if(count>0){
            throw new  RuntimeException("%s父分类下，已经存在名位:%s的子分类信息！本次添加未成功！"
                    .formatted(category.getParentId(),category.getId()));
        }
        //没有，可以添加
        save(category);
    }

    /**
     * 更新分类信息
     * @param category
     */
    @Override
    public void updateCategory(Category category) {
        //同一父类下，可以跟自己的name重复,不可以跟其他子类的name重复
        LambdaQueryWrapper<Category> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(Category::getParentId,category.getParentId());
        queryWrapper.eq(Category::getName,category.getName());
        queryWrapper.ne(Category::getId,category.getId());
        long count = count(queryWrapper);

        if(count>0){
            throw new RuntimeException("%s父类下有%s的子类信息，更新失败".formatted(category.getParentId(),category.getName()));
        }
        updateById(category);
    }

    /**
     * 删除分类信息  一级标题不能删除,分类下有题目不能删除
     * @param id
     */
    @Override
    public void deleteCategory(Long id) {
        //判断是否是一级标题
        Category categoryId = getById(id);
        if(categoryId.getParentId() == 0){
            throw new RuntimeException("不能删除一级标题！");
        }
        //判断是否存在关联题目
        LambdaQueryWrapper<Question>  queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(Question::getCategoryId,id);
        Long count = questionMapper.selectCount(queryWrapper);
        if(count>0)
            throw new RuntimeException("当前的:%s分类，关联了%s道题目,无法删除！".formatted(id, count));
        //进行删除
        removeById(id);
    }

}